# coding:utf-8
import os
import time
import base64

from PIL import Image
from flask import request, current_app
from flask_restful import Api, Resource
from io import BytesIO
from sqlalchemy import or_

from app.api.codes import PARAMS_ILLEGAL, SUCCESS
from app.api.supplier_codes import NOT_ENGINEER, NO_PACK, IS_USER_LEVEL_6
from app.api.supplier_schemas import user_tag_schema, vouchers_schema
from app.api.user_schemas import user_notify_schema
from app.api_v2.codes import BUSINESS_REQUIRED, CALL_SELF, CALL_FAILED
from app.api_v2.views import Response, AppAuthResource
from app.api_v2.user_schemas import (
    user_edit_schema, user_info_schema, user_pack_schema,
    user_avatar_schema, user_area_schema,
    mobile_schema, user_card_schema
)
from app.op.constant import UserType, BusinessDisplay, AreaType, UserLevel, UserCreditRule
from app.op.models import UserTag, Area, WxUser, User, UserInfo, Follow, Voucher
from app.relationship.constant import FRIEND_LIST_KEY
from app.relationship.models import InviteLog
from common.constant import TAIWAN_CODE, REGISTRATION_USER_HASH
from common.seven_moor import WebCall

api = Api()


@api.resource('/user/avatar')
class UserAvatarResource(AppAuthResource):
    """
    created by chenhj at 2017/11/20
    
    """
    def put(self):
        if self.user.status == UserType.ENGINEER.value:
            return Response(NOT_ENGINEER)

        data, errors = user_avatar_schema.load(request.get_json())
        if errors:
            return Response(
                PARAMS_ILLEGAL.new_format_msg(list(errors.values())[0][0]))

        im = Image.open(BytesIO(base64.b64decode(data['img'])))
        path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../api/img/avatar')
        filename = '{filename}.{format}'.format(
            format=im.format.lower(), filename=self.user.id
        )
        im.save('{path}/{filename}'.format(path=path, filename=filename), im.format)

        self.user.avatar = 'avatar/{filename}?{timestamp}'.format(
            filename=filename, timestamp=int(time.time())
        )
        return Response(SUCCESS, {
            'img': self.user.avatar_url
        })


@api.resource('/user')
class UserResource(AppAuthResource):
    """
    created by chenhj at 2017/11/20

    """
    def put(self):
        data, errors = user_edit_schema.load(request.get_json())
        if errors:
            return Response(PARAMS_ILLEGAL.new_format_msg(list(errors.values())[0][0]))

        # 更新用户信息
        self.user.nickname = data.get('nickname', self.user.nickname)
        self.user.gender = data.get('gender', self.user.gender)
        if 'com' in data:
            self.user.com = data['com']
        self.user.pos = data.get('pos', self.user.pos)
        self.user.addr = data.get('addr', self.user.addr)
        area_id = data.get('area_id', self.user.area_id)
        if area_id != self.user.area_id:
            area = Area.get_by_args(id=area_id, type=AreaType.CITY.value)
            if area:
                prov = Area.get_by_id(area.pid)
                self.user.area_id = area_id
                self.user.city = area.name
                self.user.prov = prov.name

        user_info = user_info_schema.dump(self.user)[0]

        return Response(body=dict(user=user_info))

    def get(self):
        """
        create by ld_wu 2017-11-21
        获取用户信息
        :return:
        """
        user_info = user_info_schema.dump(self.user)[0]
        user_info['opening_time'] = None
        enterprise = self.user.enterprises.first()
        if enterprise:
            if enterprise.valid:
                user_info['level'] = enterprise.level
                user_info['level_display'] = enterprise.level_display
            user_info['opening_time'] = enterprise.created_at

        pack = (
            user_pack_schema.dump(self.user.pack)[0]
            if self.user.pack
            else dict()
        )
        return Response(body=dict(
            user=user_info,
            pack=pack,
            available_vouchers=vouchers_schema.dump(
                Voucher.available_vouchers(self.user.id)
            )[0],
            unavailable_vouchers=vouchers_schema.dump(
                Voucher.unavailable_vouchers(self.user.id)
            )[0]
        ))


@api.resource('/user/<int:user_id>')
class UserInfoResource(AppAuthResource):
    """
    created by chenhj at 2017/11/20
    """

    def get(self, user_id):
        """
        create by ld_wu 2017-11-21
        获取用户信息
        :return:
        """
        user = User.query.get_or_404(user_id)
        user_info = user_info_schema.dump(user)[0]

        follow = Follow.get_by_args(
            followed_id=self.user.id,
            follower_id=user_id
        )
        alias = ''
        is_friend = False

        if follow:
            is_friend = True
            if follow.has_set_alias:
                alias = follow.alias

        user_info['alias'] = alias
        user_info['is_friend'] = is_friend

        # 移除邀请记录的红点显示(非0则移除)
        remove_red = request.args.get('remove_red', type=int)
        if remove_red:
            log = InviteLog.get_by_args(
                followed_id=self.user.id,
                follower_id=user_id
            )
            if log:
                log.red_display = False

        return Response(body=dict(user=user_info))


@api.resource('/user_info/<int:user_id>')
class UserInfoForShareResource(Resource):
    """
    create by ld_wu 2018-05-03
    获取用户信息（分享使用，无需登录）
    """

    def get(self, user_id):
        """
        create by ld_wu 2017-11-21
        获取用户信息
        :return:
        """
        user = User.query.get_or_404(user_id)
        user_info = user_info_schema.dump(user)[0]

        return Response(body=dict(user=user_info))


@api.resource('/user/<int:user_id>/call')
class UserCallResource(AppAuthResource):
    """
    create by ld_wu 2018-01-15
    """

    def get(self, user_id):
        """
        create by ld_wu 2017-11-21
        拨打用户号码
        :return:
        """
        if user_id == self.user.id:
            return Response(CALL_SELF)
        user = User.query.get_or_404(user_id)

        res = WebCall.bridge_web_call(
            Exten=self.user.mobile, Variable=user.mobile
        )
        if res.get('Succeed'):
            return Response()
        return Response(CALL_FAILED)


@api.resource('/user/business')
class UserBusinessResource(AppAuthResource):
    """
    create by ld_wu 2017-11-21
    用户从事的业务范围
    """

    def get(self):
        """
        create by ld_wu 2017-11-21
        获取业务范围
        :return:
        """
        tag = UserTag.get_by_args(user_id=self.user.id)
        tag_info = user_tag_schema.dump(tag)[0]
        return Response(
            SUCCESS,
            body=dict(
                tags=tag_info,
                business_keys=BusinessDisplay
            )
        )

    def put(self):
        """
        修改业务范围
        :return:
        """
        # 不是工程商则直接返回
        if self.user.type != UserType.ENGINEER.value:
            return Response(NOT_ENGINEER)

        tag = UserTag.default_tag(self.user.id)
        data = request.get_json()
        if not any(data.values()):
            return Response(BUSINESS_REQUIRED)
        for key in BusinessDisplay.keys():
            setattr(tag, key, data.get(key, getattr(tag, key, False)))
        self.user.has_set_business = True

        return Response()


@api.resource('/user/areas')
class UserAreaResource(AppAuthResource):
    """
    create by ld_wu 2017-11-21
    用户地域范围
    """

    def put(self):
        """
        create by ld_wu 2017-11-21
        更新地域范围
        :return:
        """
        # 不是工程商则直接返回
        if self.user.type != UserType.ENGINEER.value:
            return Response(NOT_ENGINEER)
        if not self.user.pack:
            return Response(NO_PACK)
        # 地方合作伙伴不允许修改关注区域
        if self.user.level == UserLevel.LEVEL_6.value:
            return Response(IS_USER_LEVEL_6)

        data, errors = user_area_schema.load(request.get_json())
        if errors:
            return Response(
                PARAMS_ILLEGAL.new_format_msg(list(errors.values())[0][0])
            )

        area_id = data.get('area_id', list())

        # 是否为全国，True为全国
        area_type = data.get('area_type')

        if area_type:
            areas = Area.get_list_by_args(type=AreaType.CITY.value)
        else:
            areas = Area.query.filter(
                Area.id.in_(area_id),
                Area.type == AreaType.CITY.value
            )
        area_id = [each.id for each in areas if each.id != TAIWAN_CODE]
        # 如果没有选择服务范围，默认服务工程商所在城市
        if not area_id:
            area_id = [self.user.area_id]
        self.user.has_set_business = True
        self.user.attention_areas = Area.get_list_by_ids(area_id).all()
        return Response()


@api.resource('/user/credit_rule')
class UserCreditRuleResource(Resource):
    """
    created by chenhj at 2017/12/14
    用户积分规则
    """
    def get(self):
        """
        created by chenhj at 2017/12/14

        """
        return Response(body=[
            {
                'name': '参与抢单',
                'value': UserCreditRule.ONGOING_OFFER.value
            }, {
                'name': '抢单成功',
                'value': UserCreditRule.WIN_BID.value
            }, {
                'name': '独家锁定',
                'value': UserCreditRule.DEMAND_LOCKED.value
            }, {
                'name': '恶意退款',
                'value': -UserCreditRule.GIVE_UP_MAX.value
            }, {
                'name': '成功完成项目(申报完成并通过审核)',
                'value': UserCreditRule.FINISH_DEMAND_INSTALL.value
            }
        ])


@api.resource('/user/card')
class UserCard(AppAuthResource):
    """
    create by ld_wu 2018-03-28
    用户名片
    """

    def get(self):
        data, errors = mobile_schema.load(request.args)
        if errors:
            return Response(
                PARAMS_ILLEGAL.new_format_msg(list(errors.values())[0][0]))

        mobile = data['mobile']
        users = User.query.filter(
            User.deleted_at == 0,
            User.black.is_(False),
            User.is_virt.is_(False),
            or_(
                User.mobile == mobile,
                User.nickname == mobile
            )
        ).all()

        for user in users:
            user.is_friend = current_app.redis.sismember(
                FRIEND_LIST_KEY.format(user_id=self.user.id), user.id
            )

        user_list, errors = user_card_schema.dump(users)

        return Response(body=dict(users=user_list))


@api.resource('/user/notify')
class UserNotifyUpdateAppResource(AppAuthResource):
    """
    created by chenhj at 12/01/2018

    """
    def put(self):
        """
        created by chenhj at 12/01/2018

        """
        data, errors = user_notify_schema.load(request.get_json())
        if errors:
            return Response(PARAMS_ILLEGAL.new_format_msg(list(errors.values())[0][0]))

        if 'level_3_notify' in data:
            UserInfo.default_user_info(self.user.id).level_3_notify = data['level_3_notify']

        if 'sms_alter_notify' in data:
            UserInfo.default_user_info(self.user.id).sms_alter_notify = data['sms_alter_notify']
        return Response()


@api.resource('/user/registration')
class UserRegistrationResource(AppAuthResource):
    """
    create by ld_wu 2018-06-26
    上传极光注册号
    """

    def post(self):
        data = request.get_json()
        registration_id = data.get('registration_id')
        if registration_id:
            registrations = current_app.redis.hgetall(REGISTRATION_USER_HASH)
            if registrations:
                del_keys = list()
                for reg_id, user_id in registrations.items():
                    if int(user_id) == self.user.id:
                        del_keys.append(reg_id)
                if del_keys:
                    current_app.redis.hdel(REGISTRATION_USER_HASH, *del_keys)
            current_app.redis.hset(
                REGISTRATION_USER_HASH, registration_id, self.user.id
            )
        return Response()
